package com.example.design.model;

/**
 * 模板方法
 * 模拟茶和咖啡的冲泡过程
 *
 * 茶
 *  1.把水煮沸
 *  2.用沸水冲泡茶
 *  3.把茶倒进杯子
 *  4.加柠檬
 *
 *  咖啡
 *  1.把水煮沸
 *  2.用沸水侵泡咖啡
 *  3.把咖啡倒进杯子
 *  4.加糖和牛奶
 *
 *  1和3 抽离出来  第三步 改为 “将饮料倒进杯子”
 */
public abstract class CaffeineBeverageWithHook {

    void perpareRecipe(){
        boilWater();
        brew();
        pourInCup();
        //具体是否成立 ，是用子类的具体返回值判断的
        if(customerWantsCondiments()){
            System.out.println("---启用钩子方法---");
            addCondiments();
        }
    }

    void boilWater(){
        System.out.println("把水煮沸;");
    }

    void pourInCup(){
        System.out.println("将饮料倒进杯子");
    }
    //抽象方法，交由字类具体实现

    /**
     * 加入具体饮料
     */
    abstract void brew();

    /**
     * 加入调味剂
     */
    abstract void addCondiments();

    /**
     * 钩子方法  可用可不用
     * 用于子类有机会对模板方法中的某些步骤做出反应
     * @return
     */
    boolean customerWantsCondiments(){
        return true;
    }
}
